package sanshui.system.trade.factory.trade.riskCtr.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import sanshui.system.trade.factory.trade.TradeSystemContext;
import sanshui.system.trade.factory.trade.indicator.IndicatorCode;
import sanshui.system.trade.factory.trade.indicator.IndicatorResult;
import sanshui.system.trade.factory.trade.riskCtr.AbstractRiskStrategy;
import sanshui.system.trade.factory.trade.riskCtr.RiskCtrCode;
import sanshui.system.trade.factory.trade.strategy.StrategyCode;
import sanshui.system.trade.factory.trade.strategy.StrategyResult;
import sanshui.system.trade.factory.trade.strategy.impl.M45Strategy;
import sanshui.system.trade.model.PositionAccModel;
import sanshui.system.trade.util.TradePositionUtil;

import java.util.List;
import java.util.Map;

@Component
public class TurtleAtrRistCtl extends AbstractRiskStrategy {
    private static final Logger logger = LoggerFactory.getLogger(TurtleAtrRistCtl.class);

    private final int riskPercentage = 50; // 可承担风险百分比 100%%

    @Override
    public RiskCtrCode getRiskName() {
        return RiskCtrCode.TURTLE_ATR;
    }
    @Override
    public String getDesc() {
        return RiskCtrCode.TURTLE_ATR.getMessage();
    }


    /**
     * 卖出-风控逻辑
     *
     * */
    @Override
    protected void sell(String code, StrategyResult strategyResult, Map<String, StrategyResult> sellMap, TradeSystemContext tradeSystemContext) {
        // 获取指标
        IndicatorResult indicatorResult = strategyResult.getIndicatorResult();
        Long initValue = tradeSystemContext.getAccount().getInitValue();

        List<String> atr14List = indicatorResult.getParamMap().get(IndicatorCode.ATR14.key());
        List<String> trList = indicatorResult.getParamMap().get(IndicatorCode.TR.key());

        if (atr14List == null || atr14List.size() <= 1 || trList == null || trList.size() < 1){
            // 不满足风控需要的指标
            logger.warn("不满足该风控需要的ATR的指标, 使用默认风控[全卖出], code:{}, message:{}", this.getRiskName(), this.getDesc());
            super.sell(code, strategyResult, sellMap, tradeSystemContext);
            return;
        }
        long currentATR = Long.parseLong(trList.get(0));

        // 当前价格低于 买入价格-2ATR ，止损点，需要平仓一个单位
        Map<String, PositionAccModel> holdPositionList = tradeSystemContext.getHoldPositionMap();
        PositionAccModel targetPosition = holdPositionList.get(code);
        if (null == targetPosition){
            // 还没有持有
            logger.warn("当前还未持有，无法触发【卖出】海龟交易仓位风控");
            strategyResult.setNum(0);
            return;
        }

        Long nowPrice = targetPosition.getNowPrice();
        Long entryPrice = targetPosition.getEntryPrice();
        // 计算实时头寸
        Long unit = this.calculatePositionSize(initValue, currentATR, riskPercentage);
        if (nowPrice < (entryPrice - 2 * currentATR)){
            logger.warn("触发风控, 按照头寸卖出，单位:{}， 当前持有:{}", unit, targetPosition.getNumTotal());
            strategyResult.setNum(unit);
        }
    }

    @Override
    protected void buy(String code, StrategyResult strategyResult, Map<String, StrategyResult> buyMap, TradeSystemContext tradeSystemContext) {
        // 获取指标
        IndicatorResult indicatorResult = strategyResult.getIndicatorResult();
        Long initValue = tradeSystemContext.getAccount().getInitValue();

        List<String> atr14List = indicatorResult.getParamMap().get(IndicatorCode.ATR14.key());
        List<String> trList = indicatorResult.getParamMap().get(IndicatorCode.TR.key());

        if (atr14List == null || atr14List.size() <= 1 || trList == null || trList.size() < 1){
            // 不满足风控需要的指标
            logger.warn("不满足该风控需要的ATR的指标, 使用默认风控[全买入], code:{}, message:{}", this.getRiskName(), this.getDesc());
            super.buy(code, strategyResult, buyMap, tradeSystemContext);
            return;
        }
        // 计算实时头寸
        long currentATR = Long.parseLong(trList.get(0));
        long unit = this.calculatePositionSize(initValue, currentATR, riskPercentage);

        Map<String, PositionAccModel> holdPositionList = tradeSystemContext.getHoldPositionMap();
        PositionAccModel targetPosition = holdPositionList.get(code);
        if (null == targetPosition){
            // 还没有持有
            logger.warn("当前还未持有，无法触发【买入】海龟交易仓位风控, 买入头寸:{}", unit);
            strategyResult.setNum(unit);
            return;
        }
        // 当前价格达到限价 买入，一个单位，实时计算限价，共三个等级
        long nowPrice = targetPosition.getNowPrice();
        long entryPrice = targetPosition.getEntryPrice();
        int buyOpNum = targetPosition.getBuyOpNum();
        logger.warn("第一买入的价格, entryPrice:{}", entryPrice);
        long limit1 = entryPrice + 5 * currentATR / 10;
        long limit2 = limit1 + 5 * currentATR / 10;
        long limit3 = limit2 + 5 * currentATR / 10;
        logger.warn("通过第一买入的价格, 计算三个限价，limit1:{}, limit2:{}, limit3:{}", limit1, limit2, limit3);

        if (nowPrice > limit1 && buyOpNum == 1){
            logger.warn("触发限价1, 触发风控, 按照头寸买入，limit:{}, 单位:{}", limit1, unit);
            strategyResult.setNum(unit);
            return;
        }
        if (nowPrice > limit2 && buyOpNum == 2){
            logger.warn("触发限价2, 触发风控, 按照头寸买入，limit:{}, 单位:{}", limit1, unit);
            strategyResult.setNum(unit);
            return;
        }
        if (nowPrice > limit3 && buyOpNum == 3){
            logger.warn("触发限价3, 触发风控, 按照头寸买入，limit:{}, 单位:{}", limit1, unit);
            strategyResult.setNum(unit);
        }
    }

    // 计算头寸规模（股）
    /**
     * dollarRisk (分)
     * dollarRisk / atr （股）
     * dollarRisk / atr / 100 手
     * */
    private Long calculatePositionSize(Long accountBalance, Long atr, int riskPercent) {
        Long dollarRisk = accountBalance * riskPercent / 100 /100 ; // 承受的失去资金，扩大了10000倍，百分比没有除以100
        return dollarRisk / atr ;
    }

}
